package com.ruoyi.aitcommon.utils;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFFont;

import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.Type;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.reflect.ReflectUtils;

import cn.hutool.core.util.StrUtil;

public class ExcelUtils {

	private static ExcelUtil<Object> ryUtil = new ExcelUtil<Object>(Object.class);

	/**
	 * 将Excel导入为ListMap
	 * 
	 * @param is        Excel文件输入流
	 * @param sheetName 页签名字,可以为空
	 * @return ListMap 数据
	 * @throws Exception
	 */
	public static List<Map<String, Object>> importExcel(InputStream is, String sheetName) throws Exception {
//		依据文件流创建Excel对象
		Workbook wb = WorkbookFactory.create(is);
		List<Map<String, Object>> retlist = new ArrayList<Map<String, Object>>();
		Sheet sheet = null;
		if (StrUtil.isNotBlank(sheetName)) {
			// 如果指定sheet名,则取指定sheet中的内容.
			sheet = wb.getSheet(sheetName);
		} else {
			// 如果传入的sheet名不存在则默认指向第1个sheet.
			sheet = wb.getSheetAt(0);
		}
		ExceptionUtils.checkBlankOrUndefined(sheet, "文件sheet不存在");
//		表头+数据,至少两行
		if (sheet.getPhysicalNumberOfRows() <= 1)
			return retlist;

		Map<Integer, String> headMap = new HashMap<Integer, String>();
		// Excel第一行,获取表头
		Row headRow = sheet.getRow(0);
		for (int i = 0; i < headRow.getPhysicalNumberOfCells(); i++) {
			Cell cell = headRow.getCell(i);
			if (StringUtils.isNotNull(cell)) {
				String value = ryUtil.getCellValue(headRow, i).toString();
				headMap.put(i, value);
			}
		}

//		读取数据
		for (int i = 1; i < sheet.getPhysicalNumberOfRows(); i++) {
//			从第2行开始取数据,默认第一行是表头.
			Row dataRow = sheet.getRow(i);
			if (dataRow == null) {
				continue;
			}
			Map<String, Object> mapRow = new LinkedHashMap<String, Object>();
//          获取该行所有列数据
			for (int col = 0; col < headRow.getPhysicalNumberOfCells(); col++) {
				if (headMap.containsKey(col)) {
//					获取cell值
					Object val = ryUtil.getCellValue(dataRow, col);
//	                获取field字段名
					String field = headMap.get(col);
//					构造行map
					mapRow.put(field, val);
				}
			}
			retlist.add(mapRow);
		}
		return retlist;
	}

	/**
	 * 将数据输出到Excel
	 * 
	 * @param datas     数据集合
	 * @param sheetName 页签名字
	 * @return Excel文件名
	 * @throws Exception 
	 */
	public static String exportExcel(List<Map<String, Object>> datas, String sheetName) throws Exception {
		SXSSFWorkbook wb = null;
		FileOutputStream out = null;
		try {
//			内存中保持100条数据, 超出的部分刷新到磁盘上
			wb = new SXSSFWorkbook(100);
//	        创建sheet
			SXSSFSheet sheet = wb.createSheet(sheetName);

//	        创建表头样式
			CellStyle style = wb.createCellStyle();
			style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());// 设置前景色
			style.setFillPattern(FillPatternType.SOLID_FOREGROUND);// 设置填充
			XSSFFont font = (XSSFFont) wb.createFont();
			font.setBold(true);// 粗体显示
			style.setFont(font);

			int rownum = 0;
			for (Map<String, Object> data : datas) {
				if (rownum == 0) {
//	        		第一行数据会生成两行Excel,一行标题,一行数据
//	        		第一行设置标题
					Row row = sheet.createRow(rownum);
					int i = 0;
					for (String key : data.keySet()) {
						Cell cell = row.createCell(i);
//	        			key为标题
						cell.setCellValue(key);
//	        			设置样式
						cell.setCellStyle(style);
						i++;
					}
					rownum++;
//	        		第一行设置数据
					row = sheet.createRow(rownum);
					i = 0;
					for (String key : data.keySet()) {
						Cell cell = row.createCell(i);
//	        			cdata为数据
						Object cdata = data.get(key);
						if (cdata != null) {
							cell.setCellValue(cdata.toString());
						}
						i++;
					}
					rownum++;
				} else {
//	        		第二行开始设置数据
					Row row = sheet.createRow(rownum);
					int i = 0;
					for (String key : data.keySet()) {
						Cell cell = row.createCell(i);
						Object cdata = data.get(key);
						if (cdata != null) {
							cell.setCellValue(cdata.toString());
						}
						i++;
					}
					rownum++;
				}
			}

//	        保存到文件
//			uuid+文件名
			String filename = ryUtil.encodingFilename(sheetName);
//			获取文件写入路径
			String filePath = ryUtil.getAbsoluteFile(filename);
//			写入文件
			out = new FileOutputStream(filePath);
			wb.write(out);
//			返回文件名,不是文件路径
			return filename;
		} catch (Exception ex) {
			throw ex;
		} finally {
			if (wb != null) {
				try {
					wb.close();
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
			if (out != null) {
				try {
					out.close();
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
		}
	}
}
